package com.samp.util;


import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class PinyinUtils {

    public static HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
    private static final String DECOMPOSE_PINYIN_FILE = "/pinyin_decompose.txt";
    private static Map<String, String[]> decomposePinyinMap = new HashMap<>();

    private static Set<String> similarSet = new HashSet<>();

    static {
        format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
//        format.setToneType(HanyuPinyinToneType.WITH_TONE_NUMBER);
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        format.setVCharType(HanyuPinyinVCharType.WITH_V);
        //相似读间放入集合。
        similarSet.add("l:n");
        similarSet.add("z:zh");
        similarSet.add("c:ch");
        similarSet.add("s:sh");
        similarSet.add("an:ang");
        similarSet.add("en:eng");
        similarSet.add("u:ü");
    }

    /**
     * 判断两个词读音是否相近。
     * @param leftword
     * @param rightword
     * @return
     */
    public static boolean isSimilarPronunciation(String leftword, String rightword) throws Exception {
        if( StringUtils.isBlank(leftword) || StringUtils.isBlank(rightword) ){
            return false;
        }
        if( leftword.trim().length() != rightword.trim().length() ){
            return false;
        }
        for( int i = 0 ; i < leftword.length() ; i++ ){
            if( leftword.charAt(i) == rightword.charAt(i) ){
                continue;
            }
            //如果不为中文，直接return false,因为不相等.
            if( !Character.toString(leftword.charAt(i)).matches("[\\u4E00-\\u9fa5]+") ){
                return false;
            }
            String[] leftPin = PinyinHelper.toHanyuPinyinStringArray(leftword.charAt(i), format);
            String[] rightPin = PinyinHelper.toHanyuPinyinStringArray(rightword.charAt(i), format);
            //如果是多音字，一个个的比较，有一个相似就可以。
            boolean hasSimilar = false;
            for( String left: leftPin ){
                for( String right : rightPin ){
                    System.out.println("compare: "+left+", "+right);
                    if( isSimilarPinyin(left, right )){
                        hasSimilar = true;
                        System.out.println("similar ==: "+left+", "+right);
                    }
                }
            }
            if( !hasSimilar ){
                return false;
            }
        }
        return true;
    }

    private static boolean isSimilarPinyin(String leftPin, String rightPin) throws Exception{
        if( decomposePinyinMap.size() == 0 ){
            initialDecomposePinyin();
        }
        String[] left = decomposePinyinMap.get(leftPin);
        String[] right = decomposePinyinMap.get(rightPin);
        if( left == null || right == null ){
            System.out.println("no match : left="+leftPin+", rightPin="+rightPin);
            return false;
        }
        //先判断声母
        boolean similarShengMu = false;
        if( left[0].equals(right[0]) || similarSet.contains(left[0]+":"+right[0]) ||
                similarSet.contains(right[0]+":"+left[0]) ){
            similarShengMu = true;
        }
        //判断韵母
        boolean similarYunMu = false;
        if( left[1].equals(right[1]) || similarSet.contains(left[1]+":"+right[1]) ||
                similarSet.contains(right[1]+":"+left[1]) ){
            similarYunMu = true;
        }
        return similarShengMu && similarYunMu;
    }

    public static void initialDecomposePinyin() throws Exception{
        System.out.println("start initial decompose pinyin map...");
        URL fileUrl = PinyinUtils.class.getResource(DECOMPOSE_PINYIN_FILE);
        System.out.println(fileUrl.toURI());
        Path filePath = Paths.get(fileUrl.toURI());
        BufferedReader bufferReader = Files.newBufferedReader(filePath, StandardCharsets.UTF_8);
        String line;
        try {
            while( (line = bufferReader.readLine()) != null ){
                String[] splits = line.split(":");
                if( splits.length == 2 ){
                    String[] decomposes = splits[1].split("\\+");
                    if( decomposes.length == 2 ) {
//                        System.out.println(splits[0].trim()+"="+decomposes[0].trim()+","+decomposes[1].trim());
                        decomposePinyinMap.put(splits[0].trim(),
                                                new String[]{decomposes[0].trim(), decomposes[1].trim()});
                    }else {
                        System.out.println("error decompose:"+splits[1]);
                    }
                }else {
                    System.out.println("error data:"+line);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            bufferReader.close();
        }
        System.out.println("initial decomposePinyinMap size = "+decomposePinyinMap.size());
    }

    public static void main(String[] args) {
        try {
//            initialDecomposePinyin();
            boolean a = isSimilarPronunciation("中国","美国");
            System.out.println(a);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}
